home *** CD-ROM | disk | FTP | other *** search
- /*
- VGA 320 * 400 * 256 * 2 frames routines.
-
- Written by: F van der Hulst, 20/2/91
-
- These routines display pixels in 320*400 mode by modifying the VGA
- registers, as outlined in Programmer's Journal V7.1 (Jan/Feb '89)
- article, pages 18-30, by Michael Abrash.
-
- The advantage of 320 * 400, is that it gives two separate video pages,
- which can be displayed on the screen independently. These can contain
- two views of a scene, taken from slightly different viewpoints. These
- are displayed alternately on the screen, in sync with a pair of
- "chopper glasses", to give a 3D effect.
- */
-
- #include <conio.h>
-
- typedef unsigned char DacPalette[256][3];
-
- /* Setvgapalette sets the entire 256 color palette */
- /* PalBuf contains RGB values for all 256 colors */
- /* R,G,B values range from 0 to 63 */
- /* Taken from SVGA256.H, by Jordan Hargraphix Software */
-
- void setvgapalette(DacPalette *PalBuf)
- {
- struct REGPACK reg;
-
- reg.r_ax = 0x1012;
- reg.r_bx = 0;
- reg.r_cx = 256;
- reg.r_es = FP_SEG(PalBuf);
- reg.r_dx = FP_OFF(PalBuf);
- intr(0x10,®);
- }
-
-
- unsigned int act_page = 0; /* Current page being written to */
-
-
- #define VGA_SEGMENT 0xa000
- #define SC_INDEX 0x3c4
- #define GC_INDEX 0x3ce
- #define CRTC_INDEX 0x3d4
- #define DISPIO 0x3DA
-
- #define MAP_MASK 2
- #define MEMORY_MODE 4
- #define GRAPHICS_MODE 5
- #define MISCELLANEOUS 6
- #define VRT_bit 8
- #define MAX_SCAN_LINE 9
- #define START_ADDRESS_HIGH 0x0c
- #define UNDERLINE 0x14
- #define MODE_CONTROL 0x17
-
- void writepixel(int x, int y, unsigned char colour)
- {
- long addr;
-
- addr = ((x >> 2) + 320/4 * y + act_page);
- addr = ((addr & 0xffff0000l) << 4) + (addr & 0xffffL) + ((long) VGA_SEGMENT << 16);
- outport(SC_INDEX, (0x100 << (x & 3)) | MAP_MASK);
- *(char far*)addr = colour;
- }
-
- void set320x400mode(void)
- {
- struct REGPACK regs;
- unsigned char x;
-
- regs.r_ax = 0x13; /* Set 320*200*256 graphics mode via BIOS */
- intr(0x10, ®s);
-
- /* Change CPU addressing of video memory to linear (not odd/even, chain, or
- chain 4), to allow access to all 256K of display memory. Each byte will now
- control one pixel, with 4 adjacent pixels at any given address, one pixel
- per plane. */
-
- outportb(SC_INDEX, MEMORY_MODE);
- x = inportb(SC_INDEX+1);
- x &= 0xf7;
-
- /* Turn off chain 4 */
- x |= 4;
-
- /* Turn off odd/even */
- outportb(SC_INDEX+1, x);
- outportb(GC_INDEX, GRAPHICS_MODE);
- x = inportb(GC_INDEX+1);
- x &= 0xef;
-
- /* Turn off odd/even */
- outportb(GC_INDEX+1, x);
- outportb(GC_INDEX, MISCELLANEOUS);
- x = inportb(GC_INDEX+1);
- x &= 0xfd;
-
- /* Turn off chain */
- outportb(GC_INDEX+1, x);
-
- /* Now clear the whole screen, since the mode 13h set only clears 64K. Do this
- before switching CRTC out of mode 13h, so that we don't see grabage on the
- screen. */
-
- outport(SC_INDEX, 0x0f00 | MAP_MASK); /* Write to 4 planes at once */
- setmem(MK_FP(VGA_SEGMENT, 0), 0xffff, 0);
-
- /* Change mode to 320*400 by not scanning each line twice. */
- outportb(CRTC_INDEX, MAX_SCAN_LINE);
- x = inportb(CRTC_INDEX+1);
- x &= 0xe0;
-
- /* Set maximum scan line to 0 */
- outportb(CRTC_INDEX+1, x);
-
- /* Change CRTC scanning from doubleword to byte mode, allowing the CRTC to
- scan more than 64K */
- outportb(CRTC_INDEX, UNDERLINE);
- x = inportb(CRTC_INDEX+1);
- x &= 0xbf; /* Turn off doubleword */
- outportb(CRTC_INDEX+1, x);
- outportb(CRTC_INDEX, MODE_CONTROL);
- x = inportb(CRTC_INDEX+1);
- x |= 0x40; /* Turn on the byte mode bit, so memory is linear */
- outportb(CRTC_INDEX+1, x);
- }
-
-
- void end320x400mode(void)
- {
- struct REGPACK regs;
-
- regs.r_ax = 3; /* Return to text mode */
- intr(0x10, ®s);
- }
-
-
- /* Set visible page */
- void setvispage(int page)
- {
- outport(CRTC_INDEX, (page << 15) | START_ADDRESS_HIGH);
- }
-
-
- /* Set active page (page being written to */
- void setactpage(int page)
- {
- act_page = page ? 0x8000 : 0;
- }
-
-
- void WaitForVerticalRetrace(void)
- {
- static char chopper = 1;
-
- while (inportb(DISPIO) & VRT_bit)
- /* wait */ ;
-
- while ((inportb(DISPIO) & VRT_bit) == 0)
- /* wait */ ;
-
- if ((chopper++ & 1)== 0)
- outportb(0x3fc, 1);
- else
- outportb(0x3fc, 3);
- }
-
- void main(int argc, char *argv[])
- {
- set320x400mode();
-
- /* Now fill the rgb_palette structure in memory with colour info */
- setvgapalette(&rgb_palette);
-
- setactpage(0);
-
- /* Now call writepixel to put stuff on page 0 */
- setactpage(1);
-
- /* Now call writepixel to put stuff on page 1 */
- while (!kbhit())
- {
- WaitForVerticalRetrace();
- setvispage(0);
- WaitForVerticalRetrace();
- setvispage(1);
- }
- getch();
- end320x400mode();
- }
-